#pragma once
#include "sock.hpp"
#include <vector>
#include <pthread.h>
using func_t = std::function<void(int)>;
class TcpServer;
class PthreadData
{
public:
    PthreadData(TcpServer *ts, int socket)
        : _ts(ts), _socket(socket)
    {
    }
    ~PthreadData() {}
    TcpServer *_ts;
    int _socket;
};
class TcpServer
{
private:
    // static void *Routine(void *args)
    // {
    //     PthreadData *pd = (PthreadData *)args;
    //     TcpServer *server = pd->_ts;
    //     server->Excute(pd->_socket);
    //     std::cout << "111" << std::endl;
    // }
    static void *Routine(void *args)
    {
        pthread_detach(pthread_self());
        PthreadData *td = static_cast<PthreadData *>(args);
        td->_ts->Excute(td->_socket);
        close(td->_socket);
        // delete td;
        return nullptr;
    }

public:
    TcpServer(const uint16_t &port, const std::string &ip = "0.0.0.0")
    {
        _listenSock = _sock.Socket();
        _sock.Bind(_listenSock, port, ip);
        _sock.Listen(_listenSock);
    }
    // 绑定服务函数
    void BindService(func_t func)
    {
        _func.push_back(func);
    }
    // 逐一执行
    void Excute(int sock)
    {
        for (auto &f : _func)
        {
            f(sock);
        }
    }
    void start()
    {
        for (;;)
        {
            uint16_t client_port;
            std::string client_ip;
            int sockfd = _sock.Accept(_listenSock, &client_ip, &client_port);
            if (sockfd == -1)
                continue;
            logMessage(NORMAL, "create new link success, sock: %d", sockfd);
            pthread_t tid;
            PthreadData *pd = new PthreadData(this, sockfd);
            pthread_create(&tid, nullptr, Routine, pd);
        }
    }

    ~TcpServer()
    {
        if (_listenSock > 0)
        {
            close(_listenSock);
        }
    }

private:
    Sock _sock;
    int _listenSock;
    std::vector<func_t> _func;
};